using System;
using Gj;
using Unity.Collections;
using Unity.Entities;
using UnityEngine;

[WorldSystemFilter(WorldSystemFilterFlags.Disabled)]
public partial class AiExecSystem : SystemBase
{
    private byte batch;
    private BeginInitializationEntityCommandBufferSystem CommandBufferSystem;
    private EntityQuery needRefreshGroup;

    private EntityQuery needRunGroup;
    private byte part;

    protected override void OnCreate()
    {
        part = 1;
        batch = 10;
        CommandBufferSystem = World.GetOrCreateSystemManaged<BeginInitializationEntityCommandBufferSystem>();
        // 等待执行命令的
        needRunGroup = GetEntityQuery(new EntityQueryDesc
        {
            All = new[]
            {
                ComponentType.ReadOnly<AiLastCommandData>(),
                ComponentType.ReadOnly<AiBrainStateData>(),
                ComponentType.ReadOnly<EntityData>()
            },
            None = new[]
            {
                ComponentType.ReadWrite<AiLockStateData>()
            }
        });

        // 等待刷新的entity
        needRefreshGroup = GetEntityQuery(new EntityQueryDesc
        {
            All = new[]
            {
                ComponentType.ReadOnly<AiLastCommandData>(),
                ComponentType.ReadOnly<AiRunStateData>(),
                ComponentType.ReadOnly<EntityData>()
            }
        });
    }
    //    
    //    struct NeedRunJob : IJobChunk
    //    {
    //        [WriteOnly]
    //        public EntityCommandBuffer.Concurrent CommandBuffer;
    //
    //        [ReadOnly] public int batch;
    //        [ReadOnly] public ArchetypeChunkComponentType<AiLastCommandData> AiLastCommandDataType;
    //        [ReadOnly] public ArchetypeChunkComponentType<EntityData> EntityDataType;
    //        [ReadOnly] public ArchetypeChunkEntityType EntityType;
    //        [ReadOnly] public ComponentDataFromEntity<EntityData> EntityDataFromEntity;
    //        [ReadOnly] public ComponentDataFromEntity<AiTeamData> AiTeamDataFromEntity;
    //
    //        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
    //        {
    //            var aiLastCommandDataArray = chunk.GetNativeArray(AiLastCommandDataType);
    //            var entityDataArray = chunk.GetNativeArray(EntityDataType);
    //            var entities = chunk.GetNativeArray(EntityType);
    //        
    //            for (int i = 0; i < chunk.Count && i < batch; i++)
    //            {
    //                var entity = entities[i];
    //                var entityData = entityDataArray[i];
    //                var last = aiLastCommandDataArray[i];
    //                var control = (Ai) ObjectService.GetObject(entityData.id);
    //                if (control == null)
    //                {
    //                    return;
    //                }
    //                Life life = null;
    //                EntityData targetData;
    //                if (last.entity == entity)
    //                {
    //                    targetData = entityData;
    //                    life = ObjectService.GetObject(targetData.id) as Life;
    //                }
    //                else if (Entity.Null != last.entity)
    //                {
    //                    if (EntityDataFromEntity.Exists(last.entity))
    //                    {
    //                        targetData = EntityDataFromEntity[last.entity];
    //                        life = ObjectService.GetObject(targetData.id) as Life;
    //                    }
    //                }
    //                if (control.IsActive())
    //                {
    //                    var command = control.GetCommand(last.commandIndex);
    //                    command.executing = true;
    //                    CommandBuffer.AddComponent(chunkIndex, entity, new AiRunStateData());
    //                    var aiCommand = (AI_COMMAND) command.command;
    //        
    //                    // 队员跟随队长
    //                    if (AiTeamDataFromEntity.Exists(entity))
    //                    {
    //                        CommandBuffer.SetComponent(chunkIndex, entity, new AiTeamData{aiCommand = aiCommand});
    //                    }
    //                    control.ExecuteCommand(life, command);
    //                }
    //                CommandBuffer.SetSharedComponent(chunkIndex, entity, new AiBrainStateData{state = AiBrainState.Run});
    //            }
    //        }
    //    }
    //
    //    struct RefreshJob : IJobChunk
    //    {
    //        [WriteOnly]
    //        public EntityCommandBuffer.Concurrent CommandBuffer;
    //        
    //        [ReadOnly] public int batch;
    //        [ReadOnly] public ArchetypeChunkComponentType<EntityData> EntityDataType;
    //        [ReadOnly] public ArchetypeChunkEntityType EntityType;
    //        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
    //        {
    //            var entityDataArray = chunk.GetNativeArray(EntityDataType);
    //            var entities = chunk.GetNativeArray(EntityType);
    //        
    //            for (int i = 0; i < chunk.Count && i < batch; i++)
    //            {
    //                var entity = entities[i];
    //                var entityData = entityDataArray[i];
    //                var control = (Ai) ObjectService.GetObject(entityData.id);
    //                if (control == null)
    //                {
    //                    continue;
    //                }
    //                control.RefreshCommand();
    //                if (!control.IsRun())
    //                {
    //                    CommandBuffer.RemoveComponent<AiRunStateData>(chunkIndex, entity);
    //                    ObjectService.EntityManager.RemoveComponent<AiRunStateData>(entity);
    //                }
    //                
    //            }
    //        }
    //    }

    protected override void OnUpdate()
    {
        //        var EntityDataFromEntity = GetComponentDataFromEntity<EntityData>();
        //        var EntityDataType = GetArchetypeChunkComponentType<EntityData>();
        //        var EntityType = GetArchetypeChunkEntityType();
        //        var AiLastCommandDataType = GetArchetypeChunkComponentType<AiLastCommandData>();
        //        var commandBuffer = m_Barrier.CreateCommandBuffer().ToConcurrent();
        //        // 执行Ai
        //        needRunGroup.SetSharedComponentFilter(new AiBrainStateData{state = AiBrainState.WaitRun});
        //        var needRunJob = new NeedRunJob
        //        {
        //            CommandBuffer = commandBuffer,
        //            batch = batch,
        //            EntityDataFromEntity = EntityDataFromEntity,
        //            EntityType = EntityType,
        //            AiLastCommandDataType = AiLastCommandDataType,
        //            EntityDataType = EntityDataType,
        //        };
        //        inputDeps = needRunJob.Schedule(needRunGroup, inputDeps);
        //
        //        var refreshJob = new RefreshJob
        //        {
        //            EntityDataType = EntityDataType,
        //        };
        //        inputDeps = refreshJob.Schedule(needRefreshGroup, inputDeps);
        //        

        // 执行Ai
        needRunGroup.SetSharedComponentFilter(new AiBrainStateData { state = AiBrainState.WaitRun });
        if (needRunGroup.CalculateEntityCount() > 0)
        {
            var e1 = needRunGroup.ToEntityArray(Allocator.TempJob);
            var ed1 = needRunGroup.ToComponentDataArray<EntityData>(Allocator.TempJob);
            var alcd1 = needRunGroup.ToComponentDataArray<AiLastCommandData>(Allocator.TempJob);
            try
            {
                for (var i = 0; i != e1.Length && i < batch; i++)
                {
                    var entity = e1[i];
                    var entityData = ed1[i];
                    var last = alcd1[i];
                    var control = ObjectService.GetObject<Ai>(entityData.id);
                    if (control == null) continue;
                    Life life = null;
                    EntityData targetData;
                    if (last.entity == entity)
                    {
                        targetData = entityData;
                        life = ObjectService.GetObject<Life>(targetData.id);
                    }
                    else if (Entity.Null != last.entity)
                    {
                        if (EntityManager.Exists(last.entity))
                        {
                            targetData = EntityManager.GetComponentData<EntityData>(last.entity);
                            life = ObjectService.GetObject<Life>(targetData.id);
                        }
                    }

                    if (control.IsExist()) control.ExecuteCommand(last.commandIndex, life);
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }

            e1.Dispose();
            ed1.Dispose();
            alcd1.Dispose();
        }

        var all = needRefreshGroup.CalculateEntityCount();
        if (all > 0)
        {
            part += batch;
            if (part + batch > all) part = 0;
            var ed3 = needRefreshGroup.ToComponentDataArray<EntityData>(Allocator.TempJob);
            for (int i = part; i != ed3.Length && i <= part + batch; i++)
            {
                var entityData = ed3[i];
                var control = ObjectService.GetObject<Ai>(entityData.id);
                if (control == null) continue;
                control.RefreshCommand();
            }

            ed3.Dispose();
        }
    }
}